package com.springboot.oauth2.config;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Component
public class MyAuthenticationHandler
    implements AuthenticationSuccessHandler,
        AuthenticationFailureHandler,
        AccessDeniedHandler,
        AuthenticationEntryPoint {
  /**
   * 授权失败的handler
   *
   * @param request
   * @param response
   * @param exception
   * @return: void
   * @date: 2021/12/17 下午2:27
   * @author: FuJilin
   */
  @Override
  public void onAuthenticationFailure(
      HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
      throws IOException {

    response.setContentType("application/json;charset=utf-8");
    Map map = new HashMap<>();
    map.put("status", false);
    map.put("message", "认证失败");
    response.setStatus(HttpStatus.UNAUTHORIZED.value());
    response.getWriter().print(JSON.toJSONString(map));
    response.getWriter().flush();
    response.getWriter().close();
    // 也可以支持正常的跳转
    // response.sendRedirect("/login");
  }

  /**
   * 授权失败的handler
   *
   * @param request
   * @param response
   * @param authentication
   * @return: void
   * @date: 2021/12/17 下午2:27
   * @author: FuJilin
   */
  @Override
  public void onAuthenticationSuccess(
      HttpServletRequest request, HttpServletResponse response, Authentication authentication)
      throws IOException {
    response.setContentType("application/json;charset=utf-8");
    Map map = new HashMap<>();
    map.put("status", true);
    map.put("message", "认证成功");
    map.put("data", authentication);
    response.getWriter().print(JSON.toJSONString(map));
    response.getWriter().flush();
    response.getWriter().close();
  }

  /**
   * 无访问权限的handler
   *
   * @param request
   * @param response
   * @param accessDeniedException
   * @return: void
   * @date: 2021/12/17 下午2:28
   * @author: FuJilin
   */
  @Override
  public void handle(
      HttpServletRequest request,
      HttpServletResponse response,
      AccessDeniedException accessDeniedException)
      throws IOException {
    Map map = new HashMap<>();
    map.put("status", false);
    map.put("message", "无访问权限");
    response.setContentType("text/html;charset=utf-8");
    PrintWriter writer = response.getWriter();
    writer.print(JSON.toJSONString(map));
    writer.flush();
    writer.close();
  }

  /**
   * 未登录用户访问资源失败的handler
   *
   * @param request
   * @param response
   * @param authException
   * @return: void
   * @date: 2021/12/17 下午2:28
   * @author: FuJilin
   */
  @Override
  public void commence(
      HttpServletRequest request,
      HttpServletResponse response,
      AuthenticationException authException)
      throws IOException {
    authException.printStackTrace();
    if (authException != null) {
      response.setContentType("application/json;charset=utf-8");
      Map<String, Object> result = new HashMap<>();
      result.put("status", false);
      result.put("message", " [" + authException.getMessage() + "]");
      response.getWriter().print(JSONUtils.toJSONString(result));
    }
  }
}
